home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 7 / FM Towns Free Software Collection 7.iso / t_os / qa / qa.c < prev    next >
Text File  |  1993-11-30  |  13KB  |  471 lines

  1. /*
  2. ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
  3. ┃Q&A(FMTOWNS版)                /////  Tab Size : 4  /////  ┃
  4. ┃                                      /////  Margin : 120  /////  ┃
  5. ┃ QA.c    v1.0 L18                                                    ┃
  6. ┃                                                                  ┃
  7. ┃ (C)K.Konishi    16-Aug-93                                           ┃
  8. ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
  9. */
  10.  
  11. #define    MAIN
  12.  
  13. #include "Platform.h"
  14.  
  15. #include "cd.h"
  16. #include <EGB.h>
  17. #include <MOS.h>
  18. #include <CDRFRB.h>
  19. #include <string.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <time.h>
  23. #include <conio.h>
  24. #include <FMCFRB.h>
  25. #include <msdos.cf>
  26. #include "aoi_lib2.h"
  27.  
  28. AOIbuttonData    AbD[BUTTON];
  29.  
  30. #define    KeyESC        0x1b
  31. #define    Key1        0x31
  32. #define    Key9        0x39
  33. #define    KeyA        0x41
  34. #define    KeyZ        0x5A
  35. #define    Keya        0x61
  36. #define    Keyz        0x7A
  37. #define    FontSX        12
  38. #define    FontSY        12
  39. #define    FontAX        6
  40. #define    FontAY        12
  41. #define    INIT_X        120
  42. #define    INIT_Y        120
  43. #define    BUTTON_X    16
  44. #define    BUTTON_Y    16
  45. #define    BUTTON_FX    BUTTON_X + 1
  46. #define    BUTTON_FY    BUTTON_Y + 1
  47. #define    WIN_FRAME    5
  48. #define    WIN_FRAMEx2    (WIN_FRAME << 1)
  49. #define    FS_NORMAL    0
  50. #define    FS_FUTOJI    1
  51. #define    FS_SHATAI    2
  52. #define    FS_KAGEJI    4
  53. #define    FS_FUCHI    8
  54. #define    FS_UNDERL    16
  55. #define    FS_OVERL    32
  56. #define    FS_KESHIL    64
  57. #define    FS_12FONT    99
  58. #define    MAX_WIDE    70
  59. #define    ARGV_MAX    30
  60. #define    ARGV_MAX_JI    256
  61. #define MAX_ARGV_LONG_12    95
  62. #define MAX_ARGV_LONG_16    50
  63.  
  64. enum {MENU, CONSOLE, TOWNS, CDPLAYER, HIGH, LOW, CDPLAY};
  65.  
  66. void AKANEmessage(void)
  67. {
  68.     puts("Q&A V1.0  (c)1993 KUNIZO KONISHI\n");
  69.     puts("run386 QA -[オプション] [質問] [選択肢1]・・・・・・\n");
  70.     puts(" -m      :  TownsMENU上で選択する");
  71.     puts(" -c      :  コンソール上で選択する");
  72. //    puts("\nrun386 QA -[オプション] -nD(画面非表示)\n");
  73. //    puts(" -towns  :  FMTOWNSの機種を判別する");
  74.     puts(" -high   :  高速モードを設定する");
  75.     puts(" -low    :  互換モードを設定する");
  76. //    puts(" -cdplay :  CDPLAYER");
  77. }
  78.  
  79. void AKANEbaseDraw(short sx, short sy, short lx, short ly, short bx, short by)
  80. {
  81.     AOIwinBase(sx, sy, lx + 1, ly, 1);
  82.  
  83.     AOIbuttonBase(sx +  5, sy + 5, bx, by);
  84.     AOIbuttonBase(sx + 22, sy + 5, lx - 27, by);
  85.  
  86.     AOIsetButton(&AbD[1], WIN_FRAME, WIN_FRAME, BUTTON_X, BUTTON_Y);    // 終了
  87.     AOIsetButton(&AbD[2], WIN_FRAME + BUTTON_X, WIN_FRAME, lx - WIN_FRAMEx2 - BUTTON_X , BUTTON_Y);    // 移動
  88. }
  89.  
  90. void AKANEbuttonSet(short sx, short sy, short lx, short fs, char argv[][ARGV_MAX_JI], short argvLen[], int a)
  91. {
  92.     short i;
  93.     AOIstringData    asD;    // AOIstrData型の変数宣言
  94.     
  95.     asD.sx = FontSX;    // 16ドットフォントの設定
  96.     asD.sy = FontSY;
  97.     asD.ax = FontAX;
  98.     asD.ay = FontAY;
  99.     asD.sc = BLACK;
  100.     asD.ss = fs;
  101.  
  102.     if (fs != FS_12FONT) {
  103.         AOIstring(sx + WIN_FRAME + (lx >> 1) - argvLen[2] * (FontAX >> 1), sy + 2 + BUTTON_FY, &asD, argv[2]);
  104.     } else {
  105.         AOIsystem12Font(sx + WIN_FRAME + (lx >> 1) - argvLen[2] * (FontAX >> 1), sy + 3 + (BUTTON_FY >> 2),
  106.         BLACK, argv[2]);
  107.     }
  108.     if (a != 0) {
  109.         for (i = 3; i < a + 3; i++) {
  110.             AOIbuttonBase(sx + WIN_FRAME, sy + WIN_FRAME + (i - 2) * BUTTON_FY, lx - WIN_FRAMEx2, BUTTON_Y - 1);
  111.             AOIsetButton(&AbD[i], WIN_FRAME, WIN_FRAME + (i - 2) * BUTTON_FY, lx - WIN_FRAMEx2, BUTTON_Y - 1);
  112.             if (fs != FS_12FONT) {
  113.                 AOIstring(sx + WIN_FRAME + (lx >> 1) - argvLen[i] * (FontAX >> 1), sy + 2 + (i - 1) * BUTTON_FY,
  114.                      &asD, argv[i]);
  115.             } else {
  116.                 AOIsystem12Font(sx + WIN_FRAME + (lx >> 1) - argvLen[i] * (FontAX >> 1), 
  117.                     sy + 3 + (i - 2) * BUTTON_FY + (BUTTON_FY >> 2), BLACK, argv[i]);
  118.             }
  119.         }
  120.     }
  121. }
  122.  
  123. void AKANEgraphInit(void)
  124. {
  125.     int page, dpage, pri;
  126.  
  127.     EGB_resolution(work, 0, 0x43);        //  グラフィック仮想画面の設定
  128.     EGB_resolution(work, 1, 0x43);        //  グラフィック仮想画面の設定
  129.     page = EGB_getWritePage(0, 0);        //  書き込みページの読み取り
  130.     EGB_writePage(work, page | 0x40);    //  グラフィック書き込みページ
  131.     EGB_getDisplayPage(&dpage, &pri);    //  表示ページの読み取り
  132.     EGB_displayPage(work, dpage, pri);    //  グラフィック表示ページの指定
  133. }
  134.  
  135. void AKANEwideScreen(void)
  136. {
  137.     int    i;
  138.     int    para[10][2] = {
  139.         {0, 110}, {1, 802}, {4, 909}, {29, 0}, {18, 130}, {22, 130},
  140.         {9, 138}, {11, 138}, {10, 898},    {12, 898},
  141.         };
  142.  
  143.     for(i = 0; i < 10; i++) {
  144.         _outw(0x440, para[i][0]);
  145.         _outw(0x442, para[i][1]);
  146.     }
  147. }
  148.  
  149. void AKANEmouseInit(void)
  150. {
  151.     MOS_start(mwork, MosWorkSize);
  152.     MOS_typeRom(80 + 1, 0, 0, pat_work);
  153.     MOS_disp(1);
  154. }
  155.  
  156. short AKANEohtoFile(char NewArgv[][ARGV_MAX_JI], int *argc, char *argv[])
  157. {
  158.     FILE    *fp;
  159.     char    line[ARGV_MAX_JI];
  160.     char    fileName[ARGV_MAX_JI];
  161.     short    i, j;
  162. //    short    k;
  163.  
  164.     i = 0;
  165.     while ((fileName[i] = argv[2][i + 1]) != '\0')    i++;
  166.     
  167.     if ((fp = fopen(fileName, "r")) == NULL) {
  168.         perror("cannot open ohto file");
  169.         return FALSE;
  170.     }
  171.  
  172.     i = 2;
  173.     while (fgets(line, ARGV_MAX_JI, fp)) {
  174.         strcpy(NewArgv[i], line);
  175. //        printf("%s\n", NewArgv[i]);
  176.         j = -1;
  177.         do {
  178.             j++;
  179.         } while (NewArgv[i][j] != '\n');
  180.         NewArgv[i][j] = '\0';
  181. //        printf("%s\n", NewArgv[i]);
  182. //        for (k = 0; k != j + 3; k++) {
  183. //            if (NewArgv[i][k] == '\0') printf("NULL");
  184. //            else if (NewArgv[i][k] == '\n') printf("改行");
  185. //            else printf("%c", NewArgv[i][k]);
  186. //        }
  187. //        printf("\n");
  188.  
  189.         i++;
  190.     }
  191.     *argc = i;
  192.     fclose(fp);
  193.     
  194.     return TRUE;
  195. }
  196.  
  197. short AKANEmouseWork(short *retNum, int argc, char *argv[])    // TownsMENU上での操作
  198. {
  199.     short j, dmyLen = 0;
  200.     short lx, ly;
  201.     short fs = FS_NORMAL;
  202.     short argvLen[ARGV_MAX];
  203.     int    ch, mx, my;
  204.     int button = 0;
  205.     char endmark = 0;
  206.     char buttonLamp = OFF;
  207.     short sx = INIT_X,   sy = INIT_Y;
  208.     short bx = BUTTON_X, by = BUTTON_Y;
  209.     unsigned moji, encode;
  210.     char dispTmp[(640 / 8) * 480];                //  ドットデータの読み書き作業領域
  211.     char dmmyArgv[MAX_ARGV_LONG_12];
  212.  
  213.     char    Font12argv[ARGV_MAX][ARGV_MAX_JI];    //    12ドットフォント対策 全角変換後の argv
  214.     char    NewArgv[ARGV_MAX][ARGV_MAX_JI];        //    応答ファイル対策     応答ファイル読み取り後の argv
  215.     
  216.     if (argc < 3) {    //    パラメータの数をチェック
  217.         AKANEmessage();
  218.         *retNum = FALSE;
  219.         return FALSE;
  220.     }
  221.  
  222.     // fs (フォントスタイル)を決める
  223.     if (!_strcmpi(argv[1], "-m0") || !_strcmpi(argv[1], "-m")) fs = FS_NORMAL;
  224.     if (!_strcmpi(argv[1], "-m1")) fs = FS_FUTOJI;
  225.     if (!_strcmpi(argv[1], "-m2")) fs = FS_SHATAI;
  226.     if (!_strcmpi(argv[1], "-m3")) fs = FS_KAGEJI;
  227.     if (!_strcmpi(argv[1], "-m4")) fs = FS_FUCHI;
  228.     if (!_strcmpi(argv[1], "-m5")) fs = FS_UNDERL;
  229.     if (!_strcmpi(argv[1], "-m6")) fs = FS_OVERL;
  230.     if (!_strcmpi(argv[1], "-m7")) fs = FS_KESHIL;
  231.     if (!_strcmpi(argv[1], "-m8")) fs = FS_12FONT;
  232.     
  233.     if (!strncmp(argv[2], "@", 1)) {    //    応答ファイル処理 (応答ファイルの内容を NewArgv に格納)
  234.         if(AKANEohtoFile(NewArgv, &argc, argv) == FALSE) {    // 応答ファイルオープンチェック
  235.             *retNum = FALSE;
  236.             return FALSE;
  237.         }
  238.     } else {
  239.         for (j = 2; j < argc; j++) {
  240.             strcpy(NewArgv[j], argv[j]);    //    何もせずに NewArgv に格納
  241.         }
  242.     }
  243.     
  244.     for (j = 2; j < argc; j++) {
  245.         if (fs == FS_12FONT) {
  246.             ank2sjis(Font12argv[j], NewArgv[j]);                //    全角に変換後に Font12argv に格納
  247.             strncpy(dmmyArgv, Font12argv[j], MAX_ARGV_LONG_12);    //  MAX_ARGV_LONG_12 文字以上は排除
  248.             strcpy(Font12argv[j], dmmyArgv);
  249.         } else {
  250.             strcpy(Font12argv[j], NewArgv[j]);                    //    何もせずに Font12argv に格納
  251.             strncpy(dmmyArgv, Font12argv[j], MAX_ARGV_LONG_16);    //  MAX_ARGV_LONG_16 文字以上は排除
  252.             strcpy(Font12argv[j], dmmyArgv);
  253.         }
  254.         if (dmyLen < (argvLen[j] = strlen(Font12argv[j]))) dmyLen = argvLen[j];        //    身長測定
  255.     }
  256.     lx = WIN_FRAMEx2 + dmyLen * FontAX + 60;        //    lx, ly を決める
  257.     ly = WIN_FRAMEx2 + (argc - 2) * BUTTON_FY - 1;
  258.  
  259.     AKANEgraphInit();        // グラッフィクスの初期化
  260.     if ((dmyLen > MAX_WIDE) && (fs == FS_12FONT)) AKANEwideScreen();    //    一定文字数を越えた場合はワイド画面表示
  261.     AOIgetGraph(dispTmp, sx, sy, sx + lx + 7, sy + ly + 7);
  262.     AKANEbaseDraw(sx, sy, lx, ly, bx, by);    // ウインドゥ描画
  263.     AKANEbuttonSet(sx, sy, lx, fs, Font12argv, argvLen, argc - 3);
  264.     AKANEmouseInit();        // マウスの初期化
  265.     do {
  266.         MOS_rdpos(&ch, &mx, &my);
  267.         button = 0;
  268.         if (ch == 1) button = AOIbutton(sx, sy, mx, my, AbD);    // マウスの入力
  269.         moji = KYB_read(1, &encode);    // キーボートの入力
  270.         switch (moji) {
  271.             case KeyESC :        //    ESC
  272.                 button = 1;
  273.                 break;
  274.             case Key1..Key9 :    //    1~9
  275.                 button = moji - 46;
  276.                 if (argc - 3 < button - 2) button = 0;
  277.                 break;
  278.             case KeyA..KeyZ :    //    A~Z
  279.                 button = moji - 55;
  280.                 if (argc - 3 < button - 2) button = 0;
  281.                 break;
  282.             case Keya..Keyz :    //    a~z
  283.                 button = moji - 87;
  284.                 if (argc - 3 < button - 2) button = 0;
  285.                 break;
  286.         }
  287.         KYB_clrbuf();
  288.         if (button > 0) {            // ボタン反転
  289.             if (button != 18 && button != 19 && button != 20) {
  290.                 AOIbuttonLamp(sx, sy, &AbD[button]);
  291.                 buttonLamp = ON;
  292.                 MOS_typeRom(115 + 1, 0, 0, pat_work);    // マウスも変更
  293.                 if (button == 1) {
  294.                     MOS_typeRom(124 + 1, 0, 0, pat_work);
  295.                 }
  296.             }
  297.         }
  298.         switch (button) {
  299.             case 1 :
  300.                 endmark = 1;        // 終了条件設定
  301.                 *retNum = FALSE;
  302.                 break;
  303.             case 2 :                // 移動
  304.                 AOIwindowMove(dispTmp, &sx, &sy, lx, ly);
  305.                 break;
  306.             case 3..(ARGV_MAX + 2) :
  307.                 endmark = 1;        // 値を返す
  308.                 *retNum = button - 2;
  309.                 break;
  310.         }
  311.         if (buttonLamp == ON) {                            // ボタンの反転
  312.             if (button > 0) {
  313.                 AOIbuttonLamp(sx, sy, &AbD[button]);
  314.                 buttonLamp = OFF;
  315.                 MOS_typeRom(80 + 1, 0, 0, pat_work);    // マウスも元通り
  316.             }
  317.         }
  318.     } while (endmark != 1);
  319.     MOS_end();
  320.     AOIputGraph(dispTmp, sx, sy, sx + lx + 7, sy + ly + 7);
  321. }
  322.  
  323. short AKANEconsoleWork(short *retNum, int argc, char *argv[])    //    コンソール上での選択
  324. {
  325.     unsigned moji, encode;
  326.     int button = 0;
  327.     char endmark = 0;
  328.     short item = 0;
  329.     
  330.     if (argc < 3) {    //    パラメータの数をチェック
  331.         AKANEmessage();
  332.         *retNum = FALSE;
  333.         return FALSE;
  334.     }
  335.     printf("%s\n\n", argv[2]);    //    質問の表示
  336.     for (item = 3; item < argc; item++) printf("   %d. %s\n", item - 2, argv[item]);    //    選択肢の表示
  337.     if (item == 4) printf("\n何かキーを押してください\n");
  338.     else printf("\n1 ~ %d の中から選んでください", item - 3);
  339.     do {
  340.         button = 0;
  341.         moji = KYB_read(1, &encode);
  342.         switch (moji) {
  343.             case KeyESC :        //    ESC
  344.                 button = 1;
  345.                 break;
  346.             case Key1..Key9 :    //    1~9
  347.                 button = moji - 46;
  348.                 if (item - 3 < button - 2) button = 0;
  349.                 break;
  350.             case KeyA..KeyZ :    //    A~Z
  351.                 button = moji - 55;
  352.                 if (item - 3 < button - 2) button = 0;
  353.                 break;
  354.             case Keya..Keyz :    //    a~z
  355.                 button = moji - 87;
  356.                 if (item - 3 < button - 2) button = 0;
  357.                 break;
  358.         }
  359.         KYB_clrbuf();
  360.         switch (button) {
  361.             case 1 :
  362.                 endmark = 1;        // 終了条件設定
  363.                 *retNum = FALSE;
  364.                 break;
  365.             case 3..20 :
  366.                 endmark = 1;        // 値を返す
  367.                 *retNum = button - 2;
  368.                 break;
  369.             default :
  370.                 printf("\r1 ~ %d の中から選んでください", item - 3);
  371.         }
  372.     } while (endmark != 1);
  373.     printf("\n");
  374. }
  375.  
  376. void AKANEtownsWork(short *retNum, char *argv[])    //    TOWNS機種判別
  377. {
  378.     char *machine[] = {"", "初代", "2代目", "3代目", "IIUX", "IICX"};
  379.     short m;
  380.     
  381.     m = AOItownsName();
  382.     if (_strcmpi(argv[2], "-nD")) {
  383.         if (m == 0) printf("I don't know.\n");
  384.         else printf("This TOWNS is %s.\n", machine[m]);
  385.     }
  386.     *retNum = m;
  387.     return;
  388. }
  389.  
  390. void AKANEmodeWork(short *retNum, char *argv[], BYTE mode)    // TOWNS II のモード設定
  391. {
  392.     short m;
  393.     
  394.     m = AOItownsName();
  395.     if (_strcmpi(argv[2], "-nD")) {
  396.         if (1 <= m && m <= 4) {
  397.             printf("このTOWNSは%sモードを設定できません\n", (mode == HIGH) ? "高速" : "互換");
  398.         } else {
  399.             printf("%sモードに設定しました\n", (mode == HIGH) ? "高速" : "互換");
  400.         }
  401.     }
  402.     outp(0x05ec, (mode == HIGH) ? 1 : 0);
  403.     *retNum = TRUE;
  404.     return;
  405. }
  406.  
  407. void PanicMessage(void)
  408. {
  409.     puts("Q&A V1.0  (c)1993 KUNIZO KONISHI\n");
  410.     puts("QA.expは、TMENU上以外からは、起動させないで下さい。\n");
  411.     puts("もし、画面が乱れている場合は");
  412.     puts("[ESC]キーを押した後");
  413.     puts("TMENUに戻ってください。\n");
  414.     puts("コンソールによっては、画面が固定している場合もあります。\n");
  415. }
  416.  
  417. short StartingFunction(int argc, char *argv[])
  418. {
  419.     BYTE inputer;
  420.     short retNum;
  421.     
  422.     if (argc < 2) {
  423.         AKANEmessage();
  424.         return FALSE;
  425.     }
  426.     if (!strnicmp(argv[1], "-m", 2)) {    // -m -m1 -m2・・・ の場合
  427.         inputer = MENU;
  428.         PanicMessage();
  429.     } else if (!_strcmpi(argv[1], "-c")) {
  430.         inputer = CONSOLE;
  431.     } else if (!_strcmpi(argv[1], "-towns")) {
  432.         inputer = TOWNS;
  433.     } else if (!_strcmpi(argv[1], "-high")) {
  434.         inputer = HIGH;
  435.     } else if (!_strcmpi(argv[1], "-low")) {
  436.         inputer = LOW;
  437.     } else if (!_strcmpi(argv[1], "-cdplay")) {
  438.         inputer = CDPLAY;
  439.         PanicMessage();
  440.     } else {
  441.         AKANEmessage();
  442.         return FALSE;
  443.     }
  444.     
  445.     if (inputer == MENU) {        // TMENU(-m?)のときの処理
  446.         AKANEmouseWork(&retNum, argc, argv);
  447.     }
  448.     if (inputer == CONSOLE) {    // コンソール(-c)のときの処理
  449.         AKANEconsoleWork(&retNum, argc, argv);
  450.     }
  451.     if (inputer == TOWNS) {        // TOWNS機種判別(-towns)のときの処理
  452.         AKANEtownsWork(&retNum, argv);
  453.     }
  454.     if (inputer == HIGH) {        // TOWNS II の高速モード設定(-high)のときの処理
  455.         AKANEmodeWork(&retNum, argv, HIGH);
  456.     }
  457.     if (inputer == LOW) {        // TOWNS II の互換モード設定(-low)のときの処理
  458.         AKANEmodeWork(&retNum, argv, LOW);
  459.     }
  460.     if (inputer == CDPLAY) {    // CDPLAYER(-cdplay)のときの処理
  461.         extern AKANEcdplayWork(void);
  462.         retNum = AKANEcdplayWork();
  463.     }
  464.     return retNum;
  465. }
  466.  
  467. short main(int argc, char *argv[])
  468. {
  469.     return StartingFunction(argc, argv);
  470. }
  471.